﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace eslib.xml
{
    /// <summary>
    /// 配置项
    /// <remarks>
    ///     <ID 属性1="值1" 属性2="值2">
    ///         Text
    ///         <ID />
    ///         <ID />
    ///     </ID>
    /// </remarks>
    /// </summary>
    public class XmlConfigItem
    {
        #region 属性

        public string ID { get; set; }




        public List<XmlKeyValue> Attributes { get; set; }

        /// <summary>
        /// 获取属性值,找不到返回null
        /// </summary>
        /// <param name="name">属性名</param>
        /// <returns></returns>
        public string GetAttribute(string name)
        {
            XmlKeyValue kv = Attributes.Find((keyValue) =>
            {
                if (keyValue.AttributeName == name) return true;
                else return false;
            });

            if (kv == null) return null;
            return kv.AttributeValue;
        }

        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <param name="name">属性名</param>
        /// <param name="value">属性值</param>
        public void SetAttribute(string name, string value)
        {
            XmlKeyValue kv = Attributes.Find((keyValue) =>
            {
                return keyValue.AttributeName == name;
            });

            if (kv != null) kv.AttributeValue = value;
        }




        public List<XmlConfigItem> Children { get; set; }


        public string Text { get; set; }

        #endregion






        #region 查找方法

        /// <summary>
        /// 由ID获取子集
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public List<XmlConfigItem> GetChildrenByID(string id)
        {
            List<XmlConfigItem> items = new List<XmlConfigItem>();

            foreach (var item in Children)
            {
                if (item.ID == id)
                    items.Add(item);
            }

            return items;
        }


        /// <summary>
        /// 获取确定属性值的子项，找不到返回null
        /// </summary>
        /// <param name="attributeName">属性</param>
        /// <param name="value">要查找的属性值</param>
        /// <returns></returns>
        public XmlConfigItem GetChildByAttribute(string attributeName, string value)
        {
            return Children.Find((item) =>
            {
                XmlKeyValue kv = item.Attributes.Find((keyValue) =>
                {
                    return keyValue.AttributeName == attributeName;
                });
                if (kv == null) return false;

                return kv.AttributeValue == value;
            });
        }

        #endregion




        public XmlConfigItem(string id)
        {
            this.ID = id;
            Attributes = new List<XmlKeyValue>();
            Children = new List<XmlConfigItem>();
            Text = "";
        }


        public string ToXmlString()
        {
            //属性集
            string attr = "";
            if (Attributes.Count > 0)
                foreach (var a in Attributes)
                {
                    attr += string.Format(" {0}", a.ToXmlString());
                }


            //子集
            string child = "";
            if (Children.Count > 0)
                foreach (var c in Children)
                {
                    child += string.Format("{0}\r\n", c.ToXmlString());
                }


            string xml = string.Format(@"<{0}{1}>{2}{3}</{0}>",
                 ID,
                 attr != "" ? attr : "",
                 Text != "" ? Text : "",
                 child != "" ? string.Format("{0}", child) : ""
                 );

            return xml;
        }


        public override string ToString()
        {
            return ToXmlString();
        }



        /// <summary>
        /// 保存xml
        /// </summary>
        /// <param name="fileName"></param>
        public void Save(string fileName)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(string.Format(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
{0}", ToXmlString()));
            doc.Save(fileName);
        }


        /// <summary>
        /// 保存xml
        /// </summary>
        /// <param name="stream"></param>
        public void Save(Stream stream)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(string.Format(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
{0}", ToXmlString()));
            doc.Save(stream);
        }
    }








    public class XmlKeyValue
    {
        public string AttributeName { get; set; }
        public string AttributeValue { get; set; }

        public XmlKeyValue()
        {
            AttributeName = "";
            AttributeValue = "";
        }

        public string ToXmlString()
        {
            return string.Format(@"{0}=""{1}""", AttributeName, AttributeValue);
        }

        public override string ToString()
        {
            return ToXmlString();
        }
    }

}
